<?php
namespace Zwei\Retry\Tests;


use PHPUnit\Framework\TestCase;
use Zwei\Retry\Retry;
use Zwei\Retry\RetryHelper;

class RetryHelperTest extends TestCase {
    public function testOk(){
        RetryHelper::fastRetry(function() {

        });
        $this->assertTrue(true);
    }
    public function testFastRetry()
    {
        $retry = RetryHelper::fastRetry(function() {
            return 1;
        });
        $this->assertEquals(1, $retry->getResult());
        $this->assertEquals(0, $retry->getCurrentRetry());
        $this->assertEquals(3, $retry->getMaxRetry());
        $this->assertEquals(5000, $retry->getDelay());
        $this->assertTrue($retry->isCalled());
        $this->assertTrue($retry->isCalledSuccess());
        $this->assertEquals([], $retry->getExceptions());
        $this->assertEquals(null, $retry->getFirstException());
        $this->assertEquals(null, $retry->getLastException());
    }

    public function getTestRetryExceptionDataProvider()
    {
        $data = [];
        $data[] = [
            $testcase = "testRetryException-3",
            $result = null,
            $maxRetry = 3,
            $delay = 1000 * 1000,
            $currentRetry = 3,
            $delayTotalSeconds = 14
        ];

        $data[] = [
            $testcase = "testRetryException-2",
            $result = null,
            $maxRetry = 2,
            $delay = 1000 * 1000,
            $currentRetry = 2,
            $delayTotalSeconds = 6
        ];

        $data[] = [
            $testcase = "testRetryException-1",
            $result = null,
            $maxRetry = 1,
            $delay = 1000 * 1000,
            $currentRetry = 1,
            $delayTotalSeconds = 2
        ];
        return $data;
    }

    /**
     * @param $testCase
     * @param $result
     * @param $maxRetry
     * @param $delay
     * @param $currentRetry
     * @param $delayTotalSeconds
     * @return void
     * @dataProvider getTestRetryExceptionDataProvider
     */
    public function testRetryException($testCase, $result, $maxRetry, $delay, $currentRetry, $delayTotalSeconds)
    {

        $retry = RetryHelper::retry($maxRetry, $delay, function() use ($result, $currentRetry) {
            RetryHelper::retryThrowException("exception");
        });
        $this->assertEquals($result, $retry->getResult(), $testCase);
        $this->assertEquals($currentRetry, $retry->getCurrentRetry());
        $this->assertEquals($maxRetry, $retry->getMaxRetry());
        $this->assertEquals($delay, $retry->getDelay());
        $this->assertTrue($retry->isCalled());
        $this->assertFalse($retry->isCalledSuccess());
        $this->assertEquals($maxRetry, count($retry->getExceptions()));
        $this->assertEquals("exception", $retry->getFirstException()->getMessage());
        $this->assertEquals("exception", $retry->getLastException()->getMessage());
        $this->assertEquals($delayTotalSeconds, round($retry->getDelayTotalSeconds(), 0));
    }
}
